package com.ffyc.cemp.services.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ffyc.cemp.dao.mapper.IMovieMapper;
import com.ffyc.cemp.domain.entity.Movie;

import com.ffyc.cemp.domain.vo.PageVo;
import com.ffyc.cemp.services.service.IMovieService;

import com.ffyc.cemp.tools.WorldUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestBody;

import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

@Service
public class MovieServiceImpl implements IMovieService {
    @Autowired
    private IMovieMapper movieMapper;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;//存储倒排索引

    @Override
    public PageVo<List<Movie>> findAll(int curr, int pageSize) {
        IPage<Movie> page = new Page<>(curr, pageSize);
        LambdaQueryWrapper<Movie> queryWrapper = new LambdaQueryWrapper<>();
        IPage<Movie> p = movieMapper.selectPage(page, queryWrapper);
        PageVo<List<Movie>> pageVo = new PageVo<>(p.getSize(), p.getTotal(), p.getCurrent(), p.getRecords());
        return pageVo;
    }

    @Override
    public List<String> findAllType() {
        List<Movie> movies = movieMapper.selectList(null);
        return movies.stream()
                .map(Movie::getType)
                .distinct()
                .collect(Collectors.toList());
    }

    @Override
    public void addMovie(@RequestBody Movie movie) {
        movieMapper.insert(movie);
    }

    @Override
    public void wordFromDb() {
        List<Movie> movies = movieMapper.selectList(null);

        for (Movie movie : movies) {
            String name = movie.getName();
            List<String> words = WorldUtil.toWorlds(name);
            for (String word : words) {//名字列
                stringRedisTemplate.opsForSet().add(word, String.valueOf(movie.getId()));
            }

            String director = movie.getDirector();
            words = WorldUtil.toWorlds(director);
            for (String word : words) {//导演列
                stringRedisTemplate.opsForSet().add(word, String.valueOf(movie.getId()));
            }

            String stars = movie.getStars();
            words = WorldUtil.toWorlds(stars);
            for (String word : words) {//演员列
                stringRedisTemplate.opsForSet().add(word, String.valueOf(movie.getId()));
            }

        }
    }

    @Override
    public List<Movie> findByKeywords(String keywords) {
        Set<String> member = stringRedisTemplate.opsForSet().members(keywords);//从 Redis 集合里获取与关键词对应的所有成员，这些成员是电影的 ID。

        LambdaQueryWrapper<Movie> queryWrapper = new LambdaQueryWrapper<>();

        queryWrapper.in(Movie::getId, member);//查询条件为:电影 ID 存在于从 Redis 获取的 ID 集合中。


        return movieMapper.selectList(queryWrapper);//从数据库中查询电影信息。
    }

    @Override
    public List<Movie> findByDateCurrent(int pageSize) {
        LambdaQueryWrapper<Movie> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.orderByDesc(Movie::getReleaseDate);

        IPage<Movie> page = new Page<>(1, pageSize);

        IPage<Movie> p = movieMapper.selectPage(page, queryWrapper);

        return p.getRecords();
    }

    @Override
    public List<Movie> hotMovie(int num) {
        LambdaQueryWrapper<Movie> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.orderByDesc(Movie::getReleaseDate);
        IPage<Movie> page = new Page<>(1, num);
        IPage<Movie> p = movieMapper.selectPage(page,queryWrapper);
        List<Movie> records = p.getRecords();
        Collections.sort(records, new Comparator<Movie>() {
            @Override
            public int compare(Movie o1, Movie o2) {

                return o2.getRate()-o1.getRate();
            }
        });
        return records;
    }

    @Override
    public Movie findById(int movieId){
        return movieMapper.selectById(movieId);
    }
}
